package org.foreveross.que.infra.base.ddd.aop;

import java.util.ArrayList;
import java.util.List;

import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.foreveross.que.infra.base.constant.SysConstants;
import org.foreveross.que.infra.base.ddd.Exception.IndexAopException;
import org.foreveross.que.infra.base.ddd.domain.IBaseEntity;
import org.hibernate.search.jpa.FullTextEntityManager;
import org.hibernate.search.jpa.Search;
import org.springframework.stereotype.Component;

/**
 * 
 * 给实体建立全文索引的切面类；
 * 如果要建立全文索引，要配置全文索引的实体在SysConstants.LUCENE_ENTITYS 配置Class simpleName 逗号隔开
 * @author lyq
 */
@Aspect
@Component
public class FullTextIndexAspect {
	
	List<String> fullIndexEntityNames = new ArrayList<String>();
	
		public FullTextIndexAspect(){
			loadIndexEntityNames();
		}
	
	
	@Inject
	@PersistenceContext(unitName="default")
	protected EntityManager entityManager;
	
	/**
	 * 调用 EntityHibernateRepository.delete 方法时，删除索引
	 * @param entity
	 * @throws IndexAopException
	 */
	@Before(value="execution(public * org.foreveross.que.infra.base.ddd.repository.EntityHibernateRepository.delete(org.foreveross.que.infra.base.ddd.domain.IBaseEntity))" +
			"&&args(entity)",argNames="entity")
	private void deleteIndex(IBaseEntity entity) throws IndexAopException{
		if(!fullIndexEntityNames.contains(entity.getClass().getSimpleName())){
			return ;
		}
		FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager);
		fullTextEntityManager.remove(entity);
		fullTextEntityManager.close();
	}
	
	/**
	 * 调用 EntityHibernateRepository.create 方法时，新建全文索引
	 * @param entity
	 * @throws IndexAopException
	 */
	@After(value="execution(public * org.foreveross.que.infra.base.ddd.repository.EntityHibernateRepository.create(org.foreveross.que.infra.base.ddd.domain.IBaseEntity))" +
			"&&args(entity)",argNames="entity")
	private void saveIndex(JoinPoint jp,IBaseEntity entity) throws IndexAopException{
		if(!fullIndexEntityNames.contains(entity.getClass().getSimpleName())){
			return ;
		}
		FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager);
		fullTextEntityManager.index(entity);
		fullTextEntityManager.close();
		
//		fullTextEntityManager.lock(fullTextEntityManager, lockMode)
	}
	
	/**
	 * 调用 EntityHibernateRepository.update 方法时，修改全文索引
	 * @param entity
	 * @throws IndexAopException
	 */
	@After(value="execution(public * org.foreveross.que.infra.base.ddd.repository.EntityHibernateRepository.update(org.foreveross.que.infra.base.ddd.domain.IBaseEntity))" +
			"&&args(entity)",argNames="entity")
	private void updateIndex(IBaseEntity entity) throws IndexAopException{
		if(!fullIndexEntityNames.contains(entity.getClass().getSimpleName())){
			return ;
		}
		FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager);
		fullTextEntityManager.merge(entity);
		fullTextEntityManager.close();
	}
	
	/**
	 * 加载配置全文索引的entity simpleName
	 */
	private void loadIndexEntityNames(){
		String[] arr = SysConstants.LUCENE_ENTITYS.split(",");
		for(int i=0;i<arr.length;i++){
			fullIndexEntityNames.add(arr[i]);
		}
	}

}
